﻿using System.CodeDom;
using System.Collections.Generic;

namespace Wicresoft.EKA.NRemedy.CodeGenerate
{

    public class FieldComparer : IComparer<BMC.ARSystem.Field>
    {

        public int Compare(BMC.ARSystem.Field x, BMC.ARSystem.Field y)
        {
            return (int)(x.Id - y.Id);
        }
    }

    public class CSharpModelGenerateCode
    {
        public CodeCompileUnit GenerateClassByFormName(IARSchema asrsch, string namespacem, string formName, List<uint> ids, CSharpModelGeneratorDefaultFactory csmgdf)
        {

            CodeCompileUnit ccu = new CodeCompileUnit();
            IGenerateNameResolver gnr = csmgdf.CreateGenerateNameResolver();
            //root namespace
            IGenerateRootNamespace rn = csmgdf.CreateGenerateRootNamespace(namespacem);
            rn.Create(ccu);
            //import namespace
            IGenerateImportNamespace imn = csmgdf.CreateGenerateImportNamespace();
            imn.Create(ccu.Namespaces[0]);
            //class
            IGenerateClass gc = csmgdf.CreateGenerateClass();
            IGenerateClassAttribute igca = csmgdf.CreateGenerateClassAttribute();
            gc.Create(ccu.Namespaces[0], gnr.DefaultClassNameResolver(formName), formName, igca);
            //field
            IGetARFieldFilterDelegate affd = csmgdf.CreateGetARFieldFilterDelegate();
            List<BMC.ARSystem.Field> fieldSelected = new List<BMC.ARSystem.Field>();
            foreach (var f0 in ids)
            {
                fieldSelected.Add(asrsch.GetField(formName,f0));
            }
            fieldSelected.Sort(new FieldComparer());
            IGetGenerateFieldDelegate igfd = csmgdf.CreateGenerateFieldDelegate();
            GenerateFieldDelegate gfd = igfd.getGenerateFieldDelegate();
            IGenerateFieldFactory igff = csmgdf.CreateGenerateFieldFactory();
            foreach (var f1 in fieldSelected)
            {
                IGenerateField igf = igff.getGenerateFieldCreate((ARType)f1.DataType);

                try
                {
                    igf.Create(ccu.Namespaces[0].Types[0], gnr.DefaultFieldNameResolver(f1.Name), ARTypeConvert.MappingARType(f1.DataType).Name,
                        gnr.DefaultPropertyNameResolver(f1.Name), gfd);
                }
                catch (System.ArgumentNullException e)
                {
                    throw new System.InvalidOperationException("Field Name: "+f1.Name+" Field ID :"+f1.Id+" Error:"+e.Message);
                }
            }

            //property
            Dictionary<string, object> mapping = new Dictionary<string, object>();
            IGetGeneratePropertyDelegate igpd = csmgdf.CreateGeneratePropertyDelegate();
            GeneratePropertyDelegate gpd = igpd.getGeneratePropertyDelegate();
            IGeneratePropertyAttribute igpa = csmgdf.CreateGeneratePropertyAttribute();
            IGeneratePropertyFactory igpf = csmgdf.CreateGeneratePropertyFactory();
            foreach (var f2 in fieldSelected)
            {
                mapping.Clear();
                mapping.Add("DatabaseID", f2.Id);
                mapping.Add("DatabaseName", f2.Name);
                mapping.Add("DataType", (ARType)f2.DataType);
                if (f2.FieldOption == BMC.ARSystem.Constants.AR_FIELD_OPTION_DISPLAY)
                {
                    mapping.Add("BinderAccess", ModelBinderAccessLevel.OnlyUnBind);
                }
                BMC.ARSystem.Limit limit = f2.Limit;
                IGenerateProperty igp = igpf.getGeneratePropertyCreate((ARType)f2.DataType);
                igp.Create(ccu.Namespaces[0].Types[0], gnr.DefaultPropertyNameResolver(f2.Name), ARTypeConvert.MappingARType(f2.DataType).Name,
                    limit, mapping, gpd, igpa);
            }
            return ccu;
        }
    }
}
